import random
import Team

class Trat():
    class Vrchol():
        def __init__(self, data):
            self.data = data
            self.next = None

        def prejdi(self, auto):
            return self.data.prejdi(auto)
        
    def __init__(self, meno_suboru):
        self.meno_suboru = meno_suboru
        self.nazov = self.sprav_nazov(meno_suboru)
        self.zaciatok = None
        self.zakrut = 0
        self.dlzka_zakrut = 0
        self.roviniek = 0
        self.dlzka_roviniek = 0

        self.nacitat()

    def sprav_nazov(self, meno_suboru):
        nazov = meno_suboru.split(".txt")
        nazov = nazov[0].split("_!_")
        return nazov[-1]

    def nacitat(self):
        text_subor = open(self.meno_suboru, "r")

        for riadok in text_subor:
            if(riadok[0] == "#"):
                break
            if("zakruta" in riadok):
                druh, opt_rychlost, dlzka = riadok.split(";")
                self.pridaj(Zakruta(int(opt_rychlost), int(dlzka)))
                self.zakrut += 1
                self.dlzka_zakrut += int(dlzka)
            if("rovinka" in riadok):
                druh, dlzka = riadok.split(";")
                self.pridaj(Rovinka(int(dlzka)))
                self.roviniek += 1
                self.dlzka_roviniek += int(dlzka)
        self.pridaj(Pitstop())

    def prejdi_kolo(self, jazdec, pretek, c_kola):
        kolo = self.zaciatok
        cas = 0
        while(kolo is not None):
            if(isinstance(kolo.data, Pitstop)):
                if(jazdec.pitstop):
                    cas += kolo.prejdi(jazdec)
            else:
                cas += kolo.prejdi(jazdec)
            kolo = kolo.next
            
        #upravi pneumatiky a palivo
        cas, opotrebenie, spotreba = self.update_auto(jazdec, cas)

        if(jazdec.AI and jazdec.je_trening):
            ### SPRAVIT UKLADANIE JAZDEC.AI !!!
            jazdec.trening(opotrebenie, spotreba)
        if(jazdec.AI):
            if(jazdec.str):
                jazdec.logika(pretek, c_kola)
        return cas

    def update_auto(self, jazdec, cas):
        #Pneumatiky
        if(jazdec.auto.typ_pneumatiky == "S"):
            agr = 0.02
            mnz = 0.01
            cas -= jazdec.agresivita * 0.035
        if(jazdec.auto.typ_pneumatiky == "M"):
            agr = 0.015
            mnz = 0.015
            cas -= jazdec.agresivita * 0.02
        if(jazdec.auto.typ_pneumatiky == "H"):
            agr = 0.01
            mnz = 0.02
        
        koeficient_zakruta = self.dlzka_zakrut / self.zakrut
        koeficient_rovinka = self.dlzka_roviniek / self.roviniek

        opotrebenie = koeficient_zakruta * koeficient_rovinka / 15000
        opotrebenie += jazdec.agresivita * agr
        opotrebenie -= jazdec.manazment_pneumatik * mnz
        opotrebenie += random.randint(-10, 10) * 0.01

        if(opotrebenie < 0):
            if(jazdec.auto.typ_pneumatiky == "S"):
                opotrebenie = 3.5
            if(jazdec.auto.typ_pneumatiky == "M"):
                opotrebenie = 2.25
            if(jazdec.auto.typ_pneumatiky == "H"):
                opotrebenie = 1
        
        jazdec.auto.pneumatiky -= opotrebenie
        #Spotreba (tiez viazat na agresivitu)
        spotreba = 1.5 + jazdec.agresivita * 0.015
        jazdec.auto.palivo -= spotreba

        #Posielat chybove spravy?
        if(jazdec.auto.pneumatiky <= 0):
            jazdec.auto.pneumatiky = 0
            return -1, 0, 0
        if(jazdec.auto.palivo <= 0):
            jazdec.auto.palivo = 0
            return -1, 0, 0
        return cas, opotrebenie, spotreba

    def idealny_pritlak(self, jazdec=None):
        if(jazdec is None):
            jazdec = Team.Jazdec(None, rychlost=70, preciznost=70, agresivita=50, manazment_pneumatik=50)
            jazdec.auto = Team.Auto(None, 1, zrychlenie=55)
            jazdec.auto.aerodynamika = 55

        naj_pritlak = 0
        naj_cas = 9999
        for pritlak in range(1, 101):
            cas = 0
            jazdec.auto.pritlak = pritlak
            for i in range(100):
                cas += self.prejdi_kolo(jazdec)
            cas = cas / 100
            if(cas < naj_cas):
                naj_cas = cas
                naj_pritlak = pritlak
                
        jazdec.auto.pritlak = 1
        jazdec.reset_preteky()
        #print("Naj: ", naj_pritlak)
        return naj_pritlak

    def pridaj(self, data):
        if(self.zaciatok is None):
            self.zaciatok = self.Vrchol(data)
            self.aktualny = self.zaciatok
        else:
            self.aktualny.next = self.Vrchol(data)
            self.aktualny = self.aktualny.next

class Zakruta():
    def __init__(self, optimalna_rychlost, dlzka):
        self.optimalna_rychlost = optimalna_rychlost
        self.dlzka = dlzka

    def prejdi(self, jazdec):
        if(jazdec.auto.typ_pneumatiky == "S"):
            preciz = 1.1
            prc = 0.0001
            pneumat = 1.1
            pne = 0.0001
        if(jazdec.auto.typ_pneumatiky == "M"):
            preciz = 1.2
            prc = 0.002
            pneumat = 1.15
            pne = 0.00015
        if(jazdec.auto.typ_pneumatiky == "H"):
            preciz = 1.3
            prc = 0.0003
            pneumat = 1.2
            pne = 0.0002
        
        cas = self.dlzka / self.optimalna_rychlost

        preciznost = preciz - jazdec.preciznost * prc
        rychlost_j = 1.1 - jazdec.rychlost * 0.0005
        pneumatiky = pneumat - jazdec.auto.pneumatiky * pne
        aerodynamika = 1.3 - jazdec.auto.aerodynamika * 0.003
        palivo = 1 + jazdec.auto.palivo * 0.003
        nahoda = 1.05 - random.randint(1, 10) * 0.001
        #nahoda = 1
        koeficient = 1
        agresivita = 1 - jazdec.agresivita * 0.0007

        pritlak = 1.1 - jazdec.auto.pritlak * 0.001

        cas = cas * nahoda * preciznost * rychlost_j * pneumatiky
        cas = cas * aerodynamika * palivo * koeficient * agresivita
        cas = cas * pritlak

        return cas

class Rovinka():
    def __init__(self, dlzka):
        self.dlzka = dlzka

    def prejdi(self, jazdec):
        if(jazdec.auto.typ_pneumatiky == "S"):
            pneumat = 1.1
            pne = 0.001
        if(jazdec.auto.typ_pneumatiky == "M"):
            pneumat = 1.2
            pne = 0.002
        if(jazdec.auto.typ_pneumatiky == "H"):
            pneumat = 1.3
            pne = 0.003
        
        cas = self.dlzka / (jazdec.auto.max_rychlost / 3.6) 
        
        rychlost_j = 1.1 - jazdec.rychlost * 0.001
        zrychlenie = 1.1 - jazdec.auto.zrychlenie * 0.001
        aerodynamika = 1.25 - jazdec.auto.aerodynamika * 0.0025
        palivo = 1 + jazdec.auto.palivo * 0.002
        pneumatiky = pneumat - jazdec.auto.pneumatiky * pne
        agresivita = 1 - jazdec.agresivita * 0.0005
        
        pritlak = 1.1 + jazdec.auto.pritlak * 0.001

        cas = cas * rychlost_j * zrychlenie * aerodynamika * palivo * pritlak * pneumatiky

        return cas

class Pitstop():
    def __init__(self):
        self.cas = random.randint(15,24)
    def prejdi(self, jazdec):
        jazdec.pitstop = False
        
        cas = 0
        try:
            pneumatiky, palivo = jazdec.pitstop_info
            #print(pneumatiky, palivo)
            if(pneumatiky != "-"):
                cas += 15 + random.random() #za pneumatiky
                jazdec.auto.typ_pneumatiky = pneumatiky
                jazdec.auto.pneumatiky = 100
        except:
            palivo = jazdec.pitstop_info[0]

        while(jazdec.auto.palivo + palivo > 100):
            palivo -= 1
            
        cas += 0.5 * palivo
        jazdec.auto.palivo += palivo

        return self.cas + cas




    
